<template>
  <div class="excalidraw-component">
    <div ref="excalidrawContainer" class="excalidraw-container" :style="{ height: height }"></div>
  </div>
</template>

<script>
import "@excalidraw/excalidraw/index.css";
import React from 'react'
import { createRoot } from 'react-dom/client'
import { Excalidraw, exportToBlob, exportToSvg } from '@excalidraw/excalidraw'
import {lodashMap} from "@/utils/lodashUtil";

export default {
  name: 'ExcalidrawComponent',
  props: {
    // 画板资源的JSON字符串
    resourceJson: {
      type: String,
      default: null
    },
    // 是否为暗黑模式
    darkMode: {
      type: Boolean,
      default: true
    },
    // 是否只读模式
    viewMode: {
      type: Boolean,
      default: false
    },
    // 是否启用网格模式
    gridMode: {
      type: Boolean,
      default: true
    },
    // 是否启用禅模式
    zenMode: {
      type: Boolean,
      default: false
    },
    // 画板高度
    height: {
      type: String,
      default: '400px'
    }
  },
  data() {
    return {
      excalidrawRoot: null,
      excalidrawAPI: null,
      isLoaded: false,
      changeInterval: null,
      lastData: null
    }
  },
  watch: {
    // 监听resourceJson变化，更新画板
    resourceJson: {
      handler(newValue) {
        if (newValue && this.isLoaded && this.excalidrawAPI) {
          try {
            const data = JSON.parse(newValue)
            console.log("=>(ExcalidrawComponent.vue:64) data", data);
            this.updateScene({
              elements: data?.elements,
              // files:data?.files||{}
            })

            var _files=lodashMap(data?.files,i2=>i2)
            if(_files?.length){
              this.addFiles(_files)
            }

          } catch (e) {
            console.error('解析画板数据失败:', e)
          }
        }
      },
      immediate: false
    },
    // 监听暗黑模式变化
    darkMode(newValue) {
      if (this.isLoaded && this.excalidrawAPI) {
        this.excalidrawAPI.updateScene({
          appState: { theme: newValue ? 'dark' : 'light' }
        })
      }
    },
    // 监听只读模式变化
    viewMode(newValue) {
      if (this.isLoaded && this.excalidrawAPI) {
        this.excalidrawAPI.updateScene({
          appState: { viewModeEnabled: newValue }
        })
      }
    },
    // 监听网格模式变化
    gridMode(newValue) {
      if (this.isLoaded && this.excalidrawAPI) {
        this.excalidrawAPI.updateScene({
          appState: { gridSize: newValue ? 20 : null }
        })
      }
    },
    // 监听禅模式变化
    zenMode(newValue) {
      if (this.isLoaded && this.excalidrawAPI) {
        this.excalidrawAPI.updateScene({
          appState: { zenModeEnabled: newValue }
        })
      }
    }
  },
  mounted() {
    this.initializeExcalidraw()
  },
  beforeDestroy() {
    // 清除定时器
    if (this.changeInterval) {
      clearInterval(this.changeInterval)
    }
    // 卸载React组件
    if (this.excalidrawRoot) {
      this.excalidrawRoot.unmount()
    }
  },
  methods: {
    /**
     * 初始化Excalidraw
     */
    initializeExcalidraw() {
      const container = this.$refs.excalidrawContainer
      if (!container) {
        console.error('Excalidraw容器未找到')
        return
      }

      // 初始化数据
      let initialData = null
      if (this.resourceJson) {
        try {
          initialData = JSON.parse(this.resourceJson)
        } catch (e) {
          console.error('解析resourceJson失败:', e)
        }
      }

      // 创建React根元素
      this.excalidrawRoot = createRoot(container)

      // 渲染Excalidraw组件
      this.excalidrawRoot.render(
        React.createElement(Excalidraw, {
          initialData: initialData,
          theme: this.darkMode ? 'dark' : 'light',
          viewModeEnabled: this.viewMode,
          zenModeEnabled: this.zenMode,
          gridModeEnabled: this.gridMode,
          excalidrawAPI: (api) => {
            this.excalidrawAPI = api
            this.isLoaded = true
            this.$emit('loaded', api)
          }
        })
      )

      // 设置定时器监听变化
      if (!this.viewMode) {
        this.changeInterval = setInterval(() => {
          this.checkForChanges()
        }, 500) // 每500ms检查一次变化
      }
    },

    /**
     * 检查画板数据是否有变化
     */
    checkForChanges() {
      if (!this.isLoaded || !this.excalidrawAPI) return

      try {
        // 获取当前画板数据
        const sceneData = this.getSceneData()
        if (!sceneData) return

        // 转换为JSON字符串
        const currentData = JSON.stringify(sceneData)

        // 比较是否有变化
        if (this.lastData !== currentData) {
          this.lastData = currentData
          this.$emit('change', currentData)
        }
      } catch (e) {
        console.error('检查画板变化失败:', e)
      }
    },

    /**
     * 获取画板数据
     */
    getSceneData() {
      if (!this.excalidrawAPI) return null

      try {
        // 获取元素和应用状态
        const elements = this.excalidrawAPI.getSceneElements()
        const appState = this.excalidrawAPI.getAppState()
        const files = this.excalidrawAPI.getFiles();


        return { elements, appState,files }
      } catch (e) {
        console.error('获取画板数据失败:', e)
        return null
      }
    },

    /**
     * 更新画板场景
     */
    updateScene(data) {
      if (!this.excalidrawAPI) return

      try {
        this.excalidrawAPI.updateScene(data)
      } catch (e) {
        console.error('更新画板场景失败:', e)
      }
    },
    /**
     * 更新画板场景
     */
    addFiles(files) {
      if (!this.excalidrawAPI) return

      try {
        this.excalidrawAPI.addFiles(files)
      } catch (e) {
        console.error('添加文件到 画板场景失败:', e)
      }
    },

    /**
     * 导出为JSON字符串
     */
    exportToJSON() {
      const sceneData = this.getSceneData()
      if (!sceneData) return null

      try {
        return JSON.stringify(sceneData)
      } catch (e) {
        console.error('导出JSON失败:', e)
        return null
      }
    },

    /**
     * 导出为图片Blob
     */
    async exportToImage(options = {}) {
      if (!this.excalidrawAPI) return null

      try {
        const elements = this.excalidrawAPI.getSceneElements()
        if (!elements || elements.length === 0) return null

        const blob = await exportToBlob({
          elements,
          appState: {
            ...this.excalidrawAPI.getAppState(),
            exportWithDarkMode: this.darkMode,
            ...options
          },
          files: this.excalidrawAPI.getFiles()
        })

        return blob
      } catch (e) {
        console.error('导出图片失败:', e)
        return null
      }
    },

    /**
     * 导出为SVG元素
     */
    async exportToSVG(options = {}) {
      if (!this.excalidrawAPI) return null

      try {
        const elements = this.excalidrawAPI.getSceneElements()
        if (!elements || elements.length === 0) return null

        const svgElement = await exportToSvg({
          elements,
          appState: {
            ...this.excalidrawAPI.getAppState(),
            exportWithDarkMode: this.darkMode,
            ...options
          },
          files: this.excalidrawAPI.getFiles()
        })

        return svgElement
      } catch (e) {
        console.error('导出SVG失败:', e)
        return null
      }
    },

    /**
     * 清空画板
     */
    clearCanvas() {
       if (!this.excalidrawAPI) return

       try {
         this.excalidrawAPI.updateScene({
           elements: []
         })
       } catch (e) {
         console.error('清空画板失败:', e)
       }
     }
   }
}
</script>

<style scoped>
.excalidraw-component {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.excalidraw-container {
  width: 100%;
  border: 1px solid #ddd;
  border-radius: 4px;
  overflow: hidden;
}
</style>
